package com.analysis.server.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 日志分析性能监控器
 * 用于监控和分析日志处理性能指标
 */
@Component
public class LogAnalysisPerformanceMonitor {
    
    private static final Logger logger = LoggerFactory.getLogger(LogAnalysisPerformanceMonitor.class);
    
    // 性能指标统计
    private final AtomicLong totalProcessedLines = new AtomicLong(0);
    private final AtomicLong totalProcessedBytes = new AtomicLong(0);
    private final AtomicLong totalProcessingTime = new AtomicLong(0);
    private final AtomicInteger totalSlowSqlCount = new AtomicInteger(0);
    private final AtomicInteger totalFilesProcessed = new AtomicInteger(0);
    
    // 缓存统计
    private final AtomicLong maxCacheSize = new AtomicLong(0);
    private final AtomicLong totalCacheCleanups = new AtomicLong(0);
    private final AtomicLong totalCacheEvictions = new AtomicLong(0);
    
    // 正则匹配统计
    private final AtomicLong totalRegexMatches = new AtomicLong(0);
    private final AtomicLong totalRegexAttempts = new AtomicLong(0);
    
    // 错误统计
    private final AtomicLong totalErrors = new AtomicLong(0);
    private final ConcurrentHashMap<String, AtomicLong> errorTypes = new ConcurrentHashMap<>();
    
    /**
     * 开始监控
     */
    public void startMonitoring() {
        logger.debug("=== 开始性能监控 ===");
        // 移除自动重置，支持累积统计
        // resetMetrics();
    }
    
    /**
     * 记录文件处理开始
     */
    public void recordFileStart(long fileSize) {
        logger.debug("开始处理文件，大小: {} bytes", fileSize);
    }
    
    /**
     * 记录文件处理完成
     */
    public void recordFileComplete(long fileSize, long processingTime, int slowSqlCount) {
        totalProcessedBytes.addAndGet(fileSize);
        totalProcessingTime.addAndGet(processingTime);
        totalSlowSqlCount.addAndGet(slowSqlCount);
        totalFilesProcessed.incrementAndGet();
        
        double throughput = (double) fileSize / processingTime * 1000; // bytes per second
        logger.debug("文件处理完成 - 大小: {} bytes, 耗时: {} ms, 吞吐量: {:.2f} KB/s, 慢SQL: {} 个", 
                   fileSize, processingTime, throughput / 1024, slowSqlCount);
    }
    
    /**
     * 记录行处理
     */
    public void recordLineProcessed() {
        totalProcessedLines.incrementAndGet();
    }
    
    /**
     * 记录正则匹配
     */
    public void recordRegexMatch(boolean matched) {
        totalRegexAttempts.incrementAndGet();
        if (matched) {
            totalRegexMatches.incrementAndGet();
        }
    }
    
    /**
     * 记录缓存操作
     */
    public void recordCacheOperation(int currentSize, int evictedCount) {
        if (currentSize > maxCacheSize.get()) {
            maxCacheSize.set(currentSize);
        }
        if (evictedCount > 0) {
            totalCacheEvictions.addAndGet(evictedCount);
            totalCacheCleanups.incrementAndGet();
            logger.warn("缓存清理: 移除了 {} 个条目，当前大小: {}", evictedCount, currentSize);
        }
    }
    
    /**
     * 记录错误
     */
    public void recordError(String errorType, String errorMessage) {
        totalErrors.incrementAndGet();
        errorTypes.computeIfAbsent(errorType, k -> new AtomicLong(0)).incrementAndGet();
        
        if (logger.isDebugEnabled()) {
            logger.debug("错误记录 - 类型: {}, 消息: {}", errorType, errorMessage);
        }
    }
    
    /**
     * 生成性能报告
     */
    public void generatePerformanceReport() {
        long totalLines = totalProcessedLines.get();
        long totalBytes = totalProcessedBytes.get();
        long totalTime = totalProcessingTime.get();
        int totalFiles = totalFilesProcessed.get();
        int totalSlowSql = totalSlowSqlCount.get();
        
        if (totalTime == 0) {
            logger.warn("没有处理数据，无法生成性能报告");
            return;
        }
        
        // 计算性能指标
        double avgThroughput = (double) totalBytes / totalTime * 1000; // bytes per second
        double avgLinesPerSecond = (double) totalLines / totalTime * 1000;
        double regexMatchRate = totalRegexAttempts.get() > 0 ? 
            (double) totalRegexMatches.get() / totalRegexAttempts.get() * 100 : 0;
        
        logger.debug("=== 性能监控报告 ===");
        logger.debug("文件处理统计:");
        logger.debug("  - 总处理文件数: {}", totalFiles);
        logger.debug("  - 总处理字节数: {} bytes ({:.2f} MB)", totalBytes, totalBytes / 1024.0 / 1024.0);
        logger.debug("  - 总处理行数: {}", totalLines);
        logger.debug("  - 总处理时间: {} ms ({:.2f} 秒)", totalTime, totalTime / 1000.0);
        logger.debug("  - 总慢SQL数量: {}", totalSlowSql);
        
        logger.debug("性能指标:");
        logger.debug("  - 平均吞吐量: {:.2f} KB/s", avgThroughput / 1024);
        logger.debug("  - 平均处理速度: {:.2f} 行/秒", avgLinesPerSecond);
        logger.debug("  - 平均文件处理时间: {:.2f} ms", (double) totalTime / totalFiles);
        
        logger.debug("缓存统计:");
        logger.debug("  - 最大缓存大小: {}", maxCacheSize.get());
        logger.debug("  - 缓存清理次数: {}", totalCacheCleanups.get());
        logger.debug("  - 缓存驱逐数量: {}", totalCacheEvictions.get());
        
        logger.debug("正则匹配统计:");
        logger.debug("  - 总匹配尝试: {}", totalRegexAttempts.get());
        logger.debug("  - 总匹配成功: {}", totalRegexMatches.get());
        logger.debug("  - 匹配成功率: {:.2f}%", regexMatchRate);
        
        logger.debug("错误统计:");
        logger.debug("  - 总错误数: {}", totalErrors.get());
        errorTypes.forEach((type, count) -> 
            logger.debug("  - {}: {}", type, count.get()));
        
        // 性能建议
        generatePerformanceSuggestions(avgThroughput, avgLinesPerSecond, regexMatchRate);
    }
    
    /**
     * 生成性能优化建议
     */
    private void generatePerformanceSuggestions(double throughput, double linesPerSecond, double regexMatchRate) {
        logger.debug("=== 性能优化建议 ===");
        
        if (throughput < 1024 * 1024) { // 小于1MB/s
            logger.debug("⚠️  吞吐量较低，建议:");
            logger.debug("  - 增加批处理大小");
            logger.debug("  - 使用更多线程");
            logger.debug("  - 优化I/O操作");
        }
        
        if (linesPerSecond < 1000) { // 小于1000行/秒
            logger.debug("⚠️  行处理速度较慢，建议:");
            logger.debug("  - 优化正则表达式");
            logger.debug("  - 减少字符串操作");
            logger.debug("  - 使用更高效的数据结构");
        }
        
        if (regexMatchRate < 50) { // 匹配率低于50%
            logger.debug("⚠️  正则匹配效率低，建议:");
            logger.debug("  - 优化正则表达式");
            logger.debug("  - 添加预过滤条件");
            logger.debug("  - 使用更精确的匹配模式");
        }
        
        if (maxCacheSize.get() > 5000) {
            logger.debug("⚠️  缓存使用较多，建议:");
            logger.debug("  - 增加缓存清理频率");
            logger.debug("  - 优化SQL匹配逻辑");
            logger.debug("  - 考虑使用更高效的缓存策略");
        }
        
        if (totalErrors.get() > 0) {
            logger.debug("⚠️  存在错误，建议:");
            logger.debug("  - 检查日志格式一致性");
            logger.debug("  - 增强错误处理机制");
            logger.debug("  - 添加数据验证");
        }
    }
    
    /**
     * 重置指标
     */
    public void resetMetrics() {
        totalProcessedLines.set(0);
        totalProcessedBytes.set(0);
        totalProcessingTime.set(0);
        totalSlowSqlCount.set(0);
        totalFilesProcessed.set(0);
        maxCacheSize.set(0);
        totalCacheCleanups.set(0);
        totalCacheEvictions.set(0);
        totalRegexMatches.set(0);
        totalRegexAttempts.set(0);
        totalErrors.set(0);
        errorTypes.clear();
    }
    
    /**
     * 获取当前指标快照
     */
    public PerformanceSnapshot getSnapshot() {
        return new PerformanceSnapshot(
            totalProcessedLines.get(),
            totalProcessedBytes.get(),
            totalProcessingTime.get(),
            totalSlowSqlCount.get(),
            totalFilesProcessed.get(),
            maxCacheSize.get(),
            totalCacheCleanups.get(),
            totalCacheEvictions.get(),
            totalRegexMatches.get(),
            totalRegexAttempts.get(),
            totalErrors.get()
        );
    }
    
    /**
     * 性能指标快照
     */
    public static class PerformanceSnapshot {
        private final long processedLines;
        private final long processedBytes;
        private final long processingTime;
        private final int slowSqlCount;
        private final int filesProcessed;
        private final long maxCacheSize;
        private final long cacheCleanups;
        private final long cacheEvictions;
        private final long regexMatches;
        private final long regexAttempts;
        private final long errors;
        
        public PerformanceSnapshot(long processedLines, long processedBytes, long processingTime,
                                 int slowSqlCount, int filesProcessed, long maxCacheSize,
                                 long cacheCleanups, long cacheEvictions, long regexMatches,
                                 long regexAttempts, long errors) {
            this.processedLines = processedLines;
            this.processedBytes = processedBytes;
            this.processingTime = processingTime;
            this.slowSqlCount = slowSqlCount;
            this.filesProcessed = filesProcessed;
            this.maxCacheSize = maxCacheSize;
            this.cacheCleanups = cacheCleanups;
            this.cacheEvictions = cacheEvictions;
            this.regexMatches = regexMatches;
            this.regexAttempts = regexAttempts;
            this.errors = errors;
        }
        
        // Getters
        public long getProcessedLines() { return processedLines; }
        public long getProcessedBytes() { return processedBytes; }
        public long getProcessingTime() { return processingTime; }
        public int getSlowSqlCount() { return slowSqlCount; }
        public int getFilesProcessed() { return filesProcessed; }
        public long getMaxCacheSize() { return maxCacheSize; }
        public long getCacheCleanups() { return cacheCleanups; }
        public long getCacheEvictions() { return cacheEvictions; }
        public long getRegexMatches() { return regexMatches; }
        public long getRegexAttempts() { return regexAttempts; }
        public long getErrors() { return errors; }
        
        public double getThroughput() {
            return processingTime > 0 ? (double) processedBytes / processingTime * 1000 : 0;
        }
        
        public double getLinesPerSecond() {
            return processingTime > 0 ? (double) processedLines / processingTime * 1000 : 0;
        }
        
        public double getRegexMatchRate() {
            return regexAttempts > 0 ? (double) regexMatches / regexAttempts * 100 : 0;
        }
    }
} 